﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using WJP.ComponentModel;
using WJP.Configuration;
using WJP.Utils;

namespace WJP
{
    /// <summary>
    /// 框架环境
    /// </summary>
    public static class PlatformEnvironment
    {
        #region 属性

        /// <summary>
        /// 配置文件
        /// </summary>
        public static readonly PlatformConfiguration Configuration = new PlatformConfiguration();

        /// <summary>
        /// 获取应用程序环境的值提供器。
        /// </summary>
        /// <value>The provider.</value>
        public static EnvironmentProvider Provider { get; } = new EnvironmentProvider();

        /// <summary>
        /// 查找文件路径的查找算法提供器。
        /// </summary>
        public static BranchPathProvider BranchProvider { get; private set; }

        [ThreadStatic]
        private static int _threadPortalCount;
        /// <summary>
        /// 获取当前线程目前已经进入的数据门户层数。
        /// </summary>
        public static int ThreadPortalCount
        {
            get
            {
                return _threadPortalCount;
            }
            internal set
            {
                _threadPortalCount = value;
            }
        }

        /// <summary>
        /// 返回当前用户
        /// </summary>
        public static int Identity { get; set; }

        /// <summary>
        /// 当前是否正处于调试状态
        /// </summary>
        public static bool IsDebuggingEnabled
        {
            get
            {
                return Provider.IsDebuggingEnabled;
            }
        }

        #endregion

        #region 初始化方法

        /// <summary>
        /// 重置环境
        /// </summary>
        internal static void Reset()
        {
            ResetLocation();
        }

        #endregion

        #region 文件路径

        /// <summary>
        /// 使用一个相对的路径来计算绝对路径
        /// </summary>
        /// <param name="appRootRelative"></param>
        /// <returns></returns>
        public static string MapDllPath(string appRootRelative)
        {
            return Path.Combine(Provider.DllRootDirectory, appRootRelative);
        }

        /// <summary>
        /// 相对路径转换为绝对路径。
        /// </summary>
        /// <param name="appRootRelative"></param>
        /// <returns></returns>
        public static string MapAbsolutePath(string appRootRelative)
        {
            return Path.Combine(Provider.RootDirectory, appRootRelative);
        }

        /// <summary>
        /// 把绝对路径转换为相对路径。
        /// </summary>
        /// <param name="absolutePath"></param>
        /// <returns></returns>
        public static string MapRelativePath(string absolutePath)
        {
            return absolutePath.Replace(Provider.RootDirectory, string.Empty);
        }

        /// <summary>
        /// 提供一个先初始化路径的方法，这个方法可以单独先被调用。
        /// <para></para>这样，就可以通过路径找到需要的程序集，其它的初始化才能正常进行。
        /// </summary>
        internal static void InitCustomizationPath()
        {
            BranchProvider = new BranchPathProvider();
            string settingOrDefault = ConfigurationHelper.GetAppSettingOrDefault("BranchDirList", "");
            if (string.IsNullOrWhiteSpace(settingOrDefault))
                return;
            foreach (string branchAppName in settingOrDefault.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
                BranchProvider.AddBranch(branchAppName);
        }

        #endregion

        #region 应用程序位置信息

        /// <summary>
        /// 当前应用程序的位置信息。
        ///
        /// <para></para>对应的位置：
        /// <para></para>单机版：IsWPFUI = true, DataPortalMode = DirectConnect；
        /// <para></para>Web 服务器：IsWebUI = true, DataPortalMode = DirectConnect；
        /// <para></para>C/S 客户端：IsWPFUI = true, DataPortalMode = ThroughService；
        /// <para></para>C/S 服务端（默认值）：IsWPFUI = flase, IsWebUI = flase, DataPortalMode = DirectConnect；
        /// </summary>
        public static LocationInformation Location { get; } = new LocationInformation();

        /// <summary>
        /// 重置应用程序位置信息
        /// </summary>
        private static void ResetLocation()
        {
            Location.DataPortalMode = DataPortalMode.Unit;
        }

        /// <summary>
        /// 判断是否在服务端。
        /// <para>如果是单机版，则当进入至少一次数据门户后，才能算作服务端，返回true。</para>
        /// </summary>
        /// <returns></returns>
        public static bool IsOnServer()
        {
            if (Location.DataPortalMode == DataPortalMode.CSServer || Location.DataPortalMode == DataPortalMode.WebServer)
                return true;
            if (Location.DataPortalMode == DataPortalMode.Unit && ThreadPortalCount > 0)
                return true;
            return false;
        }

        /// <summary>
        /// 判断是否在客户端
        /// <para>单机版，如果还没有进入数据门户中，则同样返回 true。</para>
        /// </summary>
        /// <returns></returns>
        public static bool IsOnClient()
        {
            if (Location.DataPortalMode == DataPortalMode.CSClient)
                return true;
            if (Location.DataPortalMode == DataPortalMode.Unit && ThreadPortalCount == 0)
                return true;
            return false;
        }

        /// <summary>
        /// 判断是否需要使用代理
        /// </summary>
        /// <returns></returns>
        public static bool NeetProxy()
        {
            return Location.DataPortalMode == DataPortalMode.CSClient;
        }

        #endregion
    }
}
